home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
DDJ0192.ARJ
/
RAID.ASC
< prev
next >
Wrap
Text File
|
1991-11-21
|
14KB
|
592 lines
_THE FIVE LEVELS OF RAID_
by Mike Wiebel and Steve Johnson
[LISTING ONE]
/* sled.c */
#include <stdio.h>
#include <assert.h>
#include <csimdefs.h>
#define HMSEC(x) ((TIME)((x))) /* 1.0e-05 second */
#define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
#define SEC(x) MSEC((1000.0 * (x))) /* second */
#define MINUTE(x) SEC((60.0 * (x))) /* minute */
#define HOUR(x) MINUTE((60.0 * (x)))
#define NUM_DISKS 1 /* num. disks in simulation */
#define NUM_FE 1L /* num. front end channels */
#define NUM_BE 1L /* num. back end channels */
#define SEEK_TIME 3.83 /* avg. num. of milliseconds spent seeking */
#define LATENCY 14.22 /* milliseconds required for one rotation */
#define NUM_CYLINDERS 1113 /* num. cylinders on disk */
#define TRACKS_PER_CYL 15 /* num. tracks per cylinder */
SS_PTR cu; /* CSIM control unit pointer */
SS_PTR disk_drive; /* CSIM disk drive pointer */
MS_PTR fe_bus; /* CSIM front end channel pointer */
MS_PTR be_bus; /* CSIM back end channel pointer */
static long track=0L; /* current track backing */
static int cylinder=0; /* current cylinder backing */
static long tot_tracks=0L; /* total tracks backed */
void backup_status(done)
int *done;
{
/* determine if this disk drive is backed up. */
track++;
tot_tracks++;
if (tot_tracks == NUM_DISKS * NUM_CYLINDERS * TRACKS_PER_CYL)
*done = 1;
}
ECODE seek()
{
long num_fe; /* num. front end channels available */
if(track == 1){ /* first track requires seek */
XacAdvExponen(MSEC(SEEK_TIME));
}
if(track == TRACKS_PER_CYL){
XacAdvance(MSEC(LATENCY));/* switch cylinder and rotate */
track = 0;
cylinder++;
}
/* if channel is available transmit data; else rotational delay */
MAvail(fe_bus,&num_fe);
while(!num_fe){
XacAdvance(MSEC(LATENCY));
MAvail(fe_bus,&num_fe);
/* sled.c - 2 */
}
return(SUCCESS);
}
ECODE send_data()
{
double xfr_time;
/* transfer data back to host */
xfr_time = LATENCY;
MSeize(fe_bus,1L);
XacAdvance(MSEC(xfr_time));
MRelease(fe_bus,1L);
return(SUCCESS);
}
int sim_main(argc, argv)
int argc;
char *argv[];
{
int done=0;
int i;
/* configure system and set up CSIM statistics */
SServer(&cu,"control unit statistics");
SServer(&disk_drive,"disk drive statistics");
MServer(&fe_bus,NUM_FE,"front end channels");
MServer(&be_bus,NUM_BE,"back end channels");
/* set simulation time */
SimWarmUp(0,0);
SimRun(MINUTE(30),1);
/* simulate backup */
SSeize(disk_drive);
SSeize(cu);
MSeize(be_bus,1L);
for(i=0; i<NUM_DISKS; i++){
do{
backup_status(&done);
assert(seek() == SUCCESS);
assert(send_data() == SUCCESS);
}while(!done);
done = 0;
track = 0;
}
printf("Backup complete\n");
SimPrint();
SRelease(cu);
MRelease(be_bus,1L);
SRelease(disk_drive);
XacTerminate();
}
[LISTING TWO]
/* RAID level 1 */
#include <stdio.h>
#include <assert.h>
#include <csimdefs.h>
#define HMSEC(x) ((TIME)((x))) /* hund.milli second */
#define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
#define SEC(x) MSEC((1000.0 * (x))) /* seconds */
#define MINUTE(x) SEC((60.0 * (x))) /* minutes */
#define HOUR(x) MINUTE((60.0 * (x)))
#define NUM_DISKS 1 /* one disk; other disk is mirror */
#define NUM_FE 2L /* num. front end channels */
#define NUM_BE 2L /* num. back end channels */
#define NUM_CU 2L /* num. of control units */
#define SEEK_TIME 3.83 /* avg. num. of milliseconds spent seeking */
#define LATENCY 14.22 /* avg. num. milliseconds spent seeking */
#define NUM_CYLINDERS 2226
#define TRACKS_PER_CYL 15
MS_PTR cu; /* CSIM control unit pointer */
MS_PTR disk_drive; /* CSIM disk drive pointer */
MS_PTR fe_bus; /* CSIM front end channel pointer */
MS_PTR be_bus; /* CSIM back end channel pointer */
Q_PTR tsend;
static long track=0L;
static int curr_cylinder=0;
void backup_status(done)
int *done;
{
/* determine if this disk drive is backed up. */
track++;
if (track == TRACKS_PER_CYL){
track = 0;
curr_cylinder++;
}
if (curr_cylinder == NUM_CYLINDERS * NUM_DISKS)
*done = 1;
}
ECODE seek(cylinder_backing)
int *cylinder_backing;
{
long num_fe;
if(curr_cylinder == 0 && track == 1){ /* first track requires seek */
XacAdvExponen(MSEC(SEEK_TIME));
}
if(*cylinder_backing != curr_cylinder){
XacAdvance(MSEC(LATENCY));
*cylinder_backing = curr_cylinder;
}
return(SUCCESS);
}
/* lvl1.c - 2 */
ECODE send_data()
{
double xfr_time;
/* transfer data back to host */
xfr_time = LATENCY;
MSeize(fe_bus,1L);
XacAdvance(MSEC(xfr_time));
MRelease(fe_bus,1L);
return(SUCCESS);
}
int sim_main(argc, argv)
int argc;
char *argv[];
{
XAC_PTR xp;
BOOLEAN orig;
static int done=0;
int cylinder_backing=0;
int i;
/* configure system and set up CSIM utilities */
MServer(&disk_drive,2L,"Disk drive server statistics");
MServer(&cu,NUM_CU,"Control unit server statistics");
MServer(&fe_bus,NUM_FE,"front end channel statistics");
MServer(&be_bus,NUM_BE,"back end channel statistics");
Queue(&tsend,"Time to send data");
/* set simulation time */
SimWarmUp(0,0);
SimRun(MINUTE(17),1);
/* simulate backup */
XacSplit(&xp,&orig); /* allow each disk subsys to transfer */
MSeize(cu,1L);
MSeize(be_bus,1L);
MSeize(disk_drive,1L);
for(i=0; i<NUM_DISKS; i++){
do{
assert(seek(&cylinder_backing)==SUCCESS);
QEnter(tsend);
assert(send_data()==SUCCESS);
QLeave(tsend);
backup_status(&done);
}while(!done);
done = 0;
track = 0;
}
SimPrint();
MRelease(cu,1L);
MRelease(be_bus,1L);
MRelease(disk_drive,1L);
XacTerminate();
}
[LISTING THREE]
/* RAID level 3 */
#include <stdio.h>
#include <csimdefs.h>
#define HMSEC(x) ((TIME)((x))) /* 1.0e-05 second */
#define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
#define SEC(x) MSEC((1000.0 * (x))) /* second */
#define MINUTE(x) SEC((60.0 * (x))) /* minute */
#define HOUR(x) MINUTE((60.0 * (x)))
#define GRP_SIZE 4 /* no. data disks in parity group */
#define NUM_CHECK 1 /* no. check disks in group */
#define NUM_CHAN 2L /* no. of channels */
#define NUM_BUSS 5L /* no. busses */
#define SEEK_TIME 11.5 /* avg. num. of milliseconds spent seeking */
#define LATENCY 16.66 /* milliseconds required for one rotation */
#define TRACK_CAPACITY 40.0 /* capacity in KB */
#define XFR_RATE 10000.0 /* KB transferred per sec */
#define NUM_CYLINDERS 1900 /* no. useable cylinders on device */
#define TRACKS_PER_CYL 19 /* no. tracks per cylinder */
#define SWITCH_TIME 4 /* milliseconds */
SS_PTR raid_cu; /* CSIM RAID control unit pointer */
MS_PTR data_disk; /* CSIM array of data disks pointer */
SS_PTR check_disk; /* CSIM check disk pointer */
MS_PTR buss; /* CSIM array of busses pointer */
MS_PTR channel; /* CSIM array of channels pointer */
ECODE seek(track_tally,original,track_count)
long track_tally;
BOOLEAN original;
int *track_count;
{
if (original){
SSeize(check_disk);
}
else{
MSeize(data_disk,1L);
}
if (!track_tally){
XacAdvExponen(MSEC(SEEK_TIME));
}
if (!(*track_count) && track_tally){/* switch cylinders */
XacAdvance(MSEC(SWITCH_TIME));
}
(*track_count)++;
if (*track_count == TRACKS_PER_CYL)
*track_count = 0;
if (original){
SRelease(check_disk);
}
else{
MRelease(data_disk,1L);
}
return(SUCCESS);
}
/* lvl3.c - 2 */
ECODE transfer()
{
double xfr_time;
XAC_PTR xp;
BOOLEAN orig;
/* send data to control unit */
MSeize(buss,1L);
XacAdvance(MSEC(LATENCY));
MRelease(buss,1L);
/* send data to host */
XacSplit(&xp,&orig);
if (!orig){
xfr_time = TRACK_CAPACITY/XFR_RATE;
MSeize(channel,1L);
XacAdvance(SEC(xfr_time));
MRelease(channel,1L);
XacTerminate();
}
return(SUCCESS);
}
int sim_main(argc, argv)
int argc;
char *argv[];
{
static int done=0; /* flag indicating completion */
int track_count=0;
long track_tally=0; /* count of tracks backed up */
long backup_goal; /* total number of tracks to back up */
int i; /* counter */
XAC_PTR xp; /* CSIM transaction pointer */
BOOLEAN original; /* flag indicating presence of original xac */
/* configure system and set up CSIM */
SServer(&raid_cu,"Control unit server statistics");
SServer(&check_disk,"check disk statistics");
MServer(&data_disk,GRP_SIZE,"data disk statistics");
MServer(&buss,NUM_BUSS,"buss statistics");
MServer(&channel,NUM_CHAN,"channel statistics");
/* set simulation period */
SimWarmUp(0,0);
SimRun(MINUTE(30),1);
for(i=0; i<GRP_SIZE; i++){ /* generate xac for each disk */
XacSplit(&xp,&original);
if (!original)
break;
}
/* backup subsystem */
/* lvl3.c - 3 */
backup_goal = TRACKS_PER_CYL * NUM_CYLINDERS;
while(!done){
seek(track_tally,original,&track_count);
transfer();
track_tally++;
if (track_tally == backup_goal){
done = 1;
SimPrint();
}
}
XacTerminate();
}
[LISTING FOUR]
/* RAID level 5 */
#include <stdio.h>
#include <assert.h>
#include <csimdefs.h>
#define HMSEC(x) ((TIME)((x))) /* 1.0e-05 second */
#define MSEC(x) ((TIME)(100.0 * (x))) /* milli second */
#define SEC(x) MSEC((1000.0 * (x))) /* second */
#define MINUTE(x) SEC((60.0 * (x))) /* minute */
#define HOUR(x) MINUTE((60.0 * (x)))
#define GRP_SIZE 50 /* no. data disks in parity group */
#define NUM_CHAN 2L /* no. of channels */
#define NUM_BUSS 50L /* no. busses */
#define SEEK_TIME 11.5 /* avg. num. of milliseconds spent seeking */
#define LATENCY 16.66 /* milliseconds required for one rotation */
#define TRACK_CAPACITY 40.0 /* capacity in KB */
#define XFR_RATE 10000.0 /* KB transferred per sec */
#define NUM_CYLINDERS 1900 /* no. useable cylinders on device */
#define TRACKS_PER_CYL 19 /* no. tracks per cylinder */
#define SWITCH_TIME 4 /* milliseconds */
#define BUF_SZ 50 /* number of tracks buffer will hold */
SS_PTR raid_cu; /* CSIM RAID control unit pointer */
SAS_PTR data_disk; /* CSIM array of data disks pointer */
MS_PTR buss; /* CSIM array of busses pointer */
MS_PTR channel; /* CSIM array of channels pointer */
long buffer[BUF_SZ]; /* RAID control unit buffer */
long update[BUF_SZ]; /* RAID buffer lock */
static long last_buf=0L; /* last track written to buffer */
void buffer_search(track,bingo,slot)
long track;
int *bingo;
int *slot;
{
int i;
*bingo = 0;
for(i=0; i<BUF_SZ; i++)
if(buffer[i] == track){
*bingo = 1;
*slot = i;
}
}
ECODE buf_get(slot)
int slot;
{
double xfer_time;
XAC_PTR xp;
BOOLEAN orig;
xfer_time = TRACK_CAPACITY / (double)XFR_RATE;
XacSplit(&xp,&orig);
MSeize(channel,1L);
XacAdvance(SEC(xfer_time/2.0));
MRelease(channel,1L);
/* lvl5.c - 2 */
if(!orig){
XacTerminate();
}
buffer[slot] = -1; /* mark slot as writeable */
return(SUCCESS);
}
int find_track(track)
long track;
{
int number;
number = track;
while(number >= GRP_SIZE)
number -= GRP_SIZE;
return(number);
}
ECODE track_get()
{
MSeize(buss,1L);
MSeize(channel,1L);
XacAdvance(MSEC(LATENCY));
XacAdvance(MSEC(1));
MRelease(channel,1L);
MRelease(buss,1L);
return(SUCCESS);
}
ECODE update_buf(track)
long track;
{
XAC_PTR xp;
BOOLEAN orig;
static int i;
static int j;
int slot;
long next;
int d_num;
j = 0;
for(i=0; i<BUF_SZ; i++){
XacSplit(&xp,&orig);
if(!orig) break;
}
if(!orig){
slot = j++;
if(buffer[slot] < track && update[slot] != 1){
update[slot] = 1;
next = last_buf++;
d_num = find_track(next);
SASeize(data_disk,d_num);
XacAdvance(MSEC(LATENCY));
SARelease(data_disk,d_num);
buffer[slot] = next;
update[slot] = 0;
}
/* lvl5.c - 3 */
XacTerminate();
}
return(SUCCESS);
}
int sim_main(argc, argv)
int argc;
char *argv[];
{
XAC_PTR xp; /* CSIM transaction pointer */
BOOLEAN original; /* flag indicating presence of original xac */
static int done=0;
static long track=0L;
int disk_num;
int i;
int slot;
int bingo;
BOOLEAN avail;
/* configure system and set up CSIM */
SServer(&raid_cu,"Control unit buffer statistics");
SArray(&data_disk,GRP_SIZE,"data disk statistics");
MServer(&buss,NUM_BUSS,"buss statistics");
MServer(&channel,NUM_CHAN,"channel statistics");
for(i=0; i<BUF_SZ; i++){ /* mark buffer as empty */
buffer[i] = -1;
update[i] = 0;
}
/* set simulation period */
SimWarmUp(0,0);
SimRun(MINUTE(30),1);
while(!done){
XacSplit(&xp,&original);
if(original){
buffer_search(track,&bingo,&slot);
if(bingo){
assert(buf_get(slot) == SUCCESS);
}
else{
disk_num = find_track(track);
SAAvail(data_disk,disk_num,&avail);
SASeize(data_disk,disk_num);
buffer_search(track,&bingo,&slot);
if(bingo){
assert(buf_get(slot) == SUCCESS);
}
else{
assert(track_get() == SUCCESS);
}
SARelease(data_disk,disk_num);
}
/* lvl5.c - 3 */
if (track == GRP_SIZE * TRACKS_PER_CYL * NUM_CYLINDERS)
done = 1;
track++;
}
else{ /* maintain buffer */
assert(update_buf(track) == SUCCESS);
XacTerminate();
}
}
printf("Backup complete\n");
SimPrint();
}